package com.system.realm;

import com.alibaba.druid.util.StringUtils;
import com.system.dao.SysUserMapper;
import com.system.model.SysUser;
import com.system.model.SysUserExample;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;


public class MyRealm extends AuthorizingRealm {
    @Autowired
    SysUserMapper sysUserMapper;

    /**
     * 只有需要验证权限时才会调用, 进行鉴权但缓存中无用户的授权信息时调用.在配有缓存的情况下，只加载一次.
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {
        String username = (String) principalCollection.getPrimaryPrincipal();
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();

        System.out.println("username: "+ username);
        //随便搞个角色先
        Set<String> roles = new HashSet<>();
        roles.add("testuser");
        authorizationInfo.setRoles(roles);

        //随便给个权限先
        Set<String> permissions = new HashSet<>();
        permissions.add("testpermission");
        authorizationInfo.setStringPermissions(permissions);
        return authorizationInfo;
    }


    /**
     * 认证回调函数,登录时调用
     * 首先根据传入的用户名获取User信息；然后如果user为空，那么抛出没找到帐号异常UnknownAccountException；
     * 如果user找到但锁定了抛出锁定异常LockedAccountException；最后生成AuthenticationInfo信息，
     * 交给间接父类AuthenticatingRealm使用CredentialsMatcher进行判断密码是否匹配，
     * 如果不匹配将抛出密码错误异常IncorrectCredentialsException；
     * 另外如果密码重试此处太多将抛出超出重试次数异常ExcessiveAttemptsException；
     * 在组装SimpleAuthenticationInfo信息时， 需要传入：身份信息（用户名）、凭据（密文密码）、盐（username+salt），
     * CredentialsMatcher使用盐加密传入的明文密码和此处的密文密码进行匹配。
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        String username = (String)authenticationToken.getPrincipal();

        if(StringUtils.isEmpty(username)){
            return null;
        }

        //查询用户信息
        SysUserExample example = new SysUserExample();
        SysUserExample.Criteria criteria = example.createCriteria();
        criteria.andUsernameEqualTo(username);
        List<SysUser> users = sysUserMapper.selectByExample(example);
        if( users==null || users.size()<=0){
            return null;
        }
        SysUser user = users.get(0);
        //如果查到了填充信息,否则
        return new SimpleAuthenticationInfo(user.getUsername(),user.getPassword(),getName());
    }
}
